package com.hqd.ch03.v51.core.metrics;

import java.util.function.Supplier;

public interface StartupStep {

    /**
     * Return the name of the startup step.
     * <p>A step name describes the current action or phase. This technical
     * name should be "." namespaced and can be reused to describe other instances of
     * similar steps during application startup.
     */
    String getName();

    /**
     * Return the unique id for this step within the application startup.
     */
    long getId();

    /**
     * Return, if available, the id of the parent step.
     * <p>The parent step is the step that was started the most recently
     * when the current step was created.
     */
    Long getParentId();

    /**
     * Add a {@link Tag} to the step.
     *
     * @param key   tag key
     * @param value tag value
     */
    StartupStep tag(String key, String value);

    /**
     * Add a {@link Tag} to the step.
     *
     * @param key   tag key
     * @param value {@link Supplier} for the tag value
     */
    StartupStep tag(String key, Supplier<String> value);

    /**
     * Return the {@link Tag} collection for this step.
     */
    Tags getTags();

    /**
     * Record the state of the step and possibly other metrics like execution time.
     * <p>Once ended, changes on the step state are not allowed.
     */
    void end();


    /**
     * Immutable collection of {@link Tag}.
     */
    interface Tags extends Iterable<Tag> {
    }


    /**
     * Simple key/value association for storing step metadata.
     */
    interface Tag {

        /**
         * Return the {@code Tag} name.
         */
        String getKey();

        /**
         * Return the {@code Tag} value.
         */
        String getValue();
    }

}
